﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using FarseerPhysics.Collision;
using FarseerPhysics.Collision.Shapes;
using Somnus.Utils;
using Somnus.Core;

namespace Somnus.Objects.GameObjects
{
    class PlayableCharacter : Character
    {
        protected bool transformed = false;

        protected float humanJumpVelocity = 7;
        protected float humanMaxVelocity = 5;
        protected float humanJumpAceleration = 0.15f;
        protected float humanAceleration = 0.4f;
        
        protected float transformedJumpVelocity = 5;
        protected float transformedMaxVelocity = 10;
        protected float transformedJumpAceleration = 0.15f;
        protected float transformedAceleration = 0.6f;


        public PlayableCharacter(DreamWorld world, String name, Texture2D texture, Nullable<Rectangle> sourceRectangle, BodyType bodyType, float x, float y, float width, float height)
            : base(world, name, texture, sourceRectangle, bodyType, x, y, width, height)
        {
        }

        public override void update(GameTime gameTime)
        {
            Vector2 velocity = this.body.LinearVelocity;

            if (!transformed)
            {
                verifyHumanMovement(ref velocity);
                verifyMaxVelocity(ref velocity, humanMaxVelocity);
                verifyTransformation();
                additionalHumanCommands();
            }
            else
            {
                verifyTransformedMovement(ref velocity);
                verifyMaxVelocity(ref velocity, transformedMaxVelocity);
                verifyUntransformation();
                additionalTransformedCommands();
            }
            
            this.body.LinearVelocity = velocity;

            base.update(gameTime);
        }

        //Override nessas funções para adicionar código no update do PlayableCrahacter
        protected virtual void additionalHumanCommands()
        {
            
        }

        //Override nessas funções para adicionar código no update do PlayableCrahacter
        protected virtual void additionalTransformedCommands()
        {
            
        }


        //Override nesses métodos para expessificar como vai transformar e destransformar
        protected virtual void verifyUntransformation()
        {
            throw new NotImplementedException();
        }
        //Override nesses métodos para expessificar como vai transformar e destransformar
        protected virtual void verifyTransformation()
        {
            throw new NotImplementedException();
        }
        //override nesse método para expessificar o movimento dele transformado
        protected virtual void verifyTransformedMovement(ref Vector2 velocity)
        {
            throw new NotImplementedException();
        }

        private void verifyMaxVelocity(ref Vector2 velocity, float maxVelocity)
        {
            //Cap velocities
            if (velocity.X> (maxVelocity))
                velocity.X = maxVelocity;
            else if (velocity.X < (-maxVelocity))
                velocity.X = -maxVelocity;
        }

        private void verifyHumanMovement(ref Vector2 velocity)
        {
            if (Controller.KeyDown(Keys.Left))
            {
                velocity.X -= humanAceleration;
                this.art.inverted = true;
            }
            else if (Controller.KeyDown(Keys.Right))
            {
                velocity.X += humanAceleration;
                this.art.inverted = false;
            }

            if (Controller.KeyPressed(Keys.Up) && onGround)
            {
                velocity.Y = -humanJumpVelocity;
            }
            else if (Controller.KeyDown (Keys.Up) && !onGround && velocity.Y < 0)
            {
                velocity.Y -= humanJumpAceleration;
            }
        }
    }
}
